#pragma once

#include "ClassEntryMgr.h"
#include "SkinObjMgr.h"
#include "GlobalSkinData.h"
#include "IXMsgListenSrv.h"
#include "UIManager.h"

#define VALID_GLOBAL_DATA() if(!s_bValid)   return NULL;

class CGlobalData
{
    CGlobalData();
public:
    ~CGlobalData();

    void Init();
    void UnInit();

    static CGlobalData* GetGlobalData();

public:
    static CClassEntryMgr*     GetClassEntryMgr();
    static XSkinObjMgr*        GetSkinObjMgr();
    static CGlobalSkinData*    GetGlobalSkinData();
    static HWND                GetBallonTooltipWnd();
    static UIManager*          GetUIManager();
    static BOOL                GetDefaultWindowIcon(HICON& hBigIcon, HICON& hSmallIcon);

    static IXMsgListenSrv*     GetMsgListenSrv();

    template <class T>
    T* GetGlobalDataObject(T*& p)
    {
        VALID_GLOBAL_DATA();
        if(p == NULL)
            p = XAlloc(T);
        return p;
    }

    template <class T>
    void ReleaseGlobalDataObject(T*& p)
    {
        if(p != NULL)
        {
            XFree(p);
            p = NULL;
        }
    }

protected:
    // GlobalData
    static BOOL         s_bValid;

    // CClassEntryMgr
    CClassEntryMgr      m_ClassEntryMgr;

    // XSkinObjMgr
    XSkinObjMgr*        m_pSkinObjMgr;

    // CGlobalSkinData
    CGlobalSkinData*    m_pGlobalSkinData;

    // UIManager
    UIManager*          m_pUIManager;

    HICON               m_hDefaultWindowBigIcon;
    HICON               m_hDefaultWindowSmallIcon;

    IXMsgListenSrv*     m_pMsgListenSrv;

    HWND                m_hWndBallonTooltip;
};


#define INVOKE_GLOBALDATA_METHOD(GetData, DataType, func, ...)      \
{                                                                   \
    CGlobalData* pGlobalData = CGlobalData::GetGlobalData();        \
    if(pGlobalData != NULL)                                         \
    {                                                               \
        DataType* pData = pGlobalData->GetData();                   \
        if(pData != NULL)                                           \
            pData->func(__VA_ARGS__);                               \
    }                                                               \
}


#define INVOKE_GLOBALDATA_METHOD_R(result, GetData, DataType, func, ...)    \
{                                                                           \
    CGlobalData* pGlobalData = CGlobalData::GetGlobalData();                \
    if(pGlobalData != NULL)                                                 \
    {                                                                       \
        DataType* pData = pGlobalData->GetData();                           \
        if(pData != NULL)                                                   \
            result = pData->func(__VA_ARGS__);                              \
    }                                                                       \
}
